home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / VBSamples / Direct3D / Donuts / donuts.frm (.txt) next >
Encoding:
Visual Basic Form  |  2001-10-08  |  37.2 KB  |  997 lines

  1. VERSION 5.00
  2. Begin VB.Form frmVBDonuts 
  3.    Caption         =   "VBDonuts"
  4.    ClientHeight    =   4440
  5.    ClientLeft      =   60
  6.    ClientTop       =   345
  7.    ClientWidth     =   5355
  8.    Icon            =   "Donuts.frx":0000
  9.    LinkTopic       =   "Form1"
  10.    ScaleHeight     =   296
  11.    ScaleMode       =   3  'Pixel
  12.    ScaleWidth      =   357
  13.    StartUpPosition =   3  'Windows Default
  14. Attribute VB_Name = "frmVBDonuts"
  15. Attribute VB_GlobalNameSpace = False
  16. Attribute VB_Creatable = False
  17. Attribute VB_PredeclaredId = True
  18. Attribute VB_Exposed = False
  19. Option Explicit
  20. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  21. '  Copyright (C) 1999-2001 Microsoft Corporation.  All Rights Reserved.
  22. '  File:       Donuts.frm
  23. '  Content:    This sample shows how 2d can be simulated with Direct3D using
  24. '              transformed and lit vertices.
  25. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  26. 'Set the constant for full screen operation.
  27. Const FULLSCREENWIDTH = 640
  28. Const FULLSCREENHEIGHT = 480
  29. 'Set the number of sprites used in the sample.
  30. Const NUM_SPRITES = 100
  31. 'Set the maximum velocity of the sprites.
  32. Const MAX_VELOCITY = 1.5
  33. 'Flexible vertex format the describes transformed and lit vertices.
  34. Const FVF = D3DFVF_XYZRHW Or D3DFVF_TEX1 Or D3DFVF_DIFFUSE Or D3DFVF_SPECULAR
  35. 'This structure describes a transformed and lit vertex.
  36. Private Type TLVERTEX
  37.     x As Single
  38.     y As Single
  39.     z As Single
  40.     rhw As Single
  41.     color As Long
  42.     specular As Long
  43.     tu As Single
  44.     tv As Single
  45. End Type
  46. 'A structure that defines all the needed properties
  47. 'of the Sprite.
  48. Private Type typeSprite
  49.     AnimDimensions As Single        'The dimensions of one frame of animation.
  50.     AnimSpeed As Single             'The speed at which the animation occurs.
  51.     AnimTheta As Single             'The current animation time count.
  52.     FramesPerRow As Long            'How many animation frames are contained in one row in the texture.
  53.     FramesTotal As Long             'Total number of frames for this animation.
  54.     FrameCurrent As Single          'The current animation frame.
  55.     RowOffset As Single             'Offset of the texture start for this sprite.
  56.     SpriteDimensions As Single      'The dimensions of this sprite as will be displayed on the screen in pixels.
  57.     SpriteNum As Long               'The index of this sprite.
  58.     SpriteVerts(3) As TLVERTEX   'Vertex information for this sprite.
  59.     Velocity As D3DVECTOR2          'The velocity of this sprite.
  60.     Location As D3DVECTOR2          'The location of this sprite.
  61. End Type
  62. Dim m_Sprite(NUM_SPRITES) As typeSprite
  63. 'Dim the DirectX objects/structs the app uses.
  64. Dim dx As DirectX8
  65. Dim d3d As Direct3D8
  66. Dim dev As Direct3DDevice8
  67. Dim d3dx As D3DX8
  68. Dim d3dtBackground As Direct3DTexture8
  69. Dim d3dtSprite As Direct3DTexture8
  70. Dim m_d3dpp As D3DPRESENT_PARAMETERS
  71. 'Dim the vertices for the background DirectX logo.
  72. Dim m_MainVerts(3) As TLVERTEX
  73. 'Module level boolean that determines whether
  74. 'the app is in fullscreen or windowed.
  75. Dim m_bWindowed As Boolean
  76. 'Module level variable to store the caps of the device.
  77. Dim m_D3DCaps As D3DCAPS8
  78. 'Module level variable to store the display mode.
  79. Dim m_d3ddm As D3DDISPLAYMODE
  80. 'Module level variables to store the window dimensions.
  81. Dim m_lWindowWidth As Long
  82. Dim m_lWindowHeight As Long
  83. 'Variables to store the render surface width and height.
  84. Dim m_lClientWidth As Long
  85. Dim m_lClientHeight As Long
  86. 'Module level variable to store app state.
  87. Dim m_bRunning As Boolean
  88. Private Sub Form_Load()
  89.     'Show and size the form.
  90.     With Me
  91.         .Show
  92.         .Height = .ScaleY(300, vbPixels, vbTwips)
  93.         .Width = .ScaleX(400, vbPixels, vbTwips)
  94.     End With
  95.         
  96.     'Seed the random number generator.
  97.     Call Randomize
  98.     'Call the sub to initialize the app.
  99.     Call InitApp
  100.         
  101.     'Start the main loop of the sample.
  102.     Call MainLoop
  103. End Sub
  104. Private Sub InitApp()
  105.     '***********************************************************************
  106.     '
  107.     ' This sub initializes the application.
  108.     '
  109.     ' Parameters:
  110.     '
  111.     '           None.
  112.     '
  113.     '***********************************************************************
  114.     Dim lErrNum As Long
  115.             
  116.     'Store the current window dimensions
  117.     m_lWindowWidth = Me.ScaleWidth
  118.     m_lWindowHeight = Me.ScaleHeight
  119.     'Call the function that initializes the DirectX8, Direct3D8, and Direct3DDevice8 objects.
  120.     lErrNum = InitD3D(dx, d3d, dev, Me.hwnd)
  121.     If lErrNum Then
  122.         'There was an error. We'll need to exit out at this point.
  123.         Unload Me
  124.     End If
  125.     'Set the d3dx variable to a new D3DX8 object
  126.     Set d3dx = New D3DX8
  127.     'Call the function to load any textures.
  128.     Call InitTextures
  129. End Sub
  130. Private Sub MainLoop()
  131.     '***********************************************************************
  132.     '
  133.     ' This sub is the main loop for the sample.
  134.     '
  135.     ' Parameters:
  136.     '
  137.     '           None.
  138.     '
  139.     '***********************************************************************
  140.                 
  141.     m_bRunning = True
  142.     Do While m_bRunning
  143.         
  144.         Call RenderScene
  145.         DoEvents
  146.         
  147.     Loop
  148.                 
  149.     'Exiting app now
  150.     Unload Me
  151. End Sub
  152. Private Sub RenderScene()
  153.     '***********************************************************************
  154.     '
  155.     ' This sub handles the rendering of the scene.
  156.     '
  157.     ' Parameters:
  158.     '
  159.     '   None.
  160.     '
  161.     '***********************************************************************
  162.     On Local Error Resume Next
  163.             
  164.     Dim hr As Long
  165.     'Call TestCooperativeLevel to see what state the device is in.
  166.     hr = dev.TestCooperativeLevel
  167.     If hr = D3DERR_DEVICELOST Then
  168.         
  169.         'If the device is lost, exit and wait for it to come back.
  170.         Exit Sub
  171.     ElseIf hr = D3DERR_DEVICENOTRESET Then
  172.             
  173.         'The device became lost for some reason (probably an alt-tab) and now
  174.         'Reset() needs to be called to try and get the device back.
  175.         hr = 0
  176.         hr = ResetDevice()
  177.         
  178.         'If the device failed to be reset, exit the sub.
  179.         If hr Then Exit Sub
  180.     End If
  181.     'Make sure the app isn't minimized.
  182.     If Me.WindowState <> vbMinimized Then
  183.         
  184.         'The app is ready for rendering.
  185.         With dev
  186.                                     
  187.             'Clear the back buffer
  188.             Call .Clear(0, ByVal 0&, D3DCLEAR_TARGET, &HFF, 0, 0)
  189.             
  190.             'Begin the 3d scene
  191.             Call .BeginScene
  192.             
  193.             'Set the background texture on the device
  194.             Call .SetTexture(0, d3dtBackground)
  195.             
  196.             'Draw the 2 polygons that make up the background
  197.             Call .DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, m_MainVerts(0), Len(m_MainVerts(0)))
  198.             
  199.             'Call the sub that renders the sprites
  200.             Call RenderSprites
  201.             
  202.             'End the scene
  203.             Call .EndScene
  204.             
  205.             'Draw the graphics to the front buffer.
  206.             Call .Present(ByVal 0&, ByVal 0&, 0, ByVal 0&)
  207.             
  208.         End With
  209.     End If
  210. End Sub
  211. Private Sub RenderSprites()
  212.     '***********************************************************************
  213.     '
  214.     ' This sub handles the rendering and animation of the sprites.
  215.     '
  216.     ' Parameters:
  217.     '
  218.     '   None.
  219.     '
  220.     '***********************************************************************
  221.     Dim i As Long
  222.     Dim TexX As Single, TexY As Single
  223.     With dev
  224.         
  225.         'Set the Sprite texture on the device
  226.         Call .SetTexture(0, d3dtSprite)
  227.         
  228.         'Make sure the device supports alpha blending
  229.         If (m_D3DCaps.TextureCaps And D3DPTEXTURECAPS_ALPHA) Then
  230.             
  231.             'It does, so turn alpha blending on
  232.             Call .SetRenderState(D3DRS_ALPHABLENDENABLE, 1)
  233.         
  234.         End If
  235.                                                
  236.        For i = 0 To UBound(m_Sprite)
  237.             'Call the sub that updates the Sprite
  238.             Call UpdateSprite(i)
  239.             'Draw the 2 polygons that make up the Sprite
  240.             Call .DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, m_Sprite(i).SpriteVerts(0), Len(m_Sprite(i).SpriteVerts(0)))
  241.         Next
  242.         
  243.         
  244.         'If alpha blending was turned on
  245.          If .GetRenderState(D3DRS_ALPHABLENDENABLE) Then
  246.             
  247.             'Turn it back off
  248.             Call .SetRenderState(D3DRS_ALPHABLENDENABLE, 0)
  249.             
  250.         End If
  251.         
  252.     End With
  253. End Sub
  254. Private Sub UpdateSprite(ByVal index As Long)
  255.     '***********************************************************************
  256.     '
  257.     ' This sub updates the sprites texture coordinates and position.
  258.     ' Direc3DDevice8.
  259.     '
  260.     ' Parameters:
  261.     '
  262.     ' [IN]
  263.     '       index:      The index of the Sprite to update.
  264.     '
  265.     '***********************************************************************
  266.         
  267.     Dim TexX As Single, TexY As Single
  268.     With m_Sprite(index)
  269.                 
  270.         'Update the theta for this sprite.
  271.         .AnimTheta = .AnimTheta + .AnimSpeed
  272.         
  273.         'If the theta count is greater than one, advance the animation frame.
  274.         If .AnimTheta > 1 Then
  275.             
  276.             'Reset theta
  277.             .AnimTheta = 0
  278.             
  279.             'Advance the animation frame
  280.             .FrameCurrent = .FrameCurrent + 1
  281.             If .FrameCurrent >= .FramesTotal Then
  282.                 .FrameCurrent = 0
  283.             End If
  284.             
  285.         End If
  286.         
  287.         'Calculate the updated texture coordinates for this Sprite
  288.         TexY = ((.FrameCurrent \ .FramesPerRow) * .AnimDimensions) + .RowOffset
  289.         TexX = (.FrameCurrent Mod .FramesPerRow) * .AnimDimensions
  290.         
  291.         'Update the position of the Sprite
  292.         .Location.x = .Location.x + .Velocity.x
  293.         .Location.y = .Location.y + .Velocity.y
  294.         
  295.         .SpriteVerts(0).x = .Location.x
  296.         .SpriteVerts(0).y = .Location.y + .SpriteDimensions
  297.         .SpriteVerts(0).tu = TexX
  298.         .SpriteVerts(0).tv = TexY + .AnimDimensions
  299.         
  300.         .SpriteVerts(1).x = .Location.x
  301.         .SpriteVerts(1).y = .Location.y
  302.         .SpriteVerts(1).tu = TexX
  303.         .SpriteVerts(1).tv = TexY
  304.                 
  305.         .SpriteVerts(2).x = .Location.x + .SpriteDimensions
  306.         .SpriteVerts(2).y = .Location.y + .SpriteDimensions
  307.         .SpriteVerts(2).tu = TexX + .AnimDimensions
  308.         .SpriteVerts(2).tv = TexY + .AnimDimensions
  309.         
  310.         .SpriteVerts(3).x = .Location.x + .SpriteDimensions
  311.         .SpriteVerts(3).y = .Location.y
  312.         .SpriteVerts(3).tu = TexX + .AnimDimensions
  313.         .SpriteVerts(3).tv = TexY
  314.         
  315.         'Check to see if the Sprite hit a wall. If it did, reverse its velocity.
  316.         If .Location.x <= 0 Then
  317.             .Velocity.x = -1 * .Velocity.x
  318.         ElseIf .Location.x + .SpriteDimensions >= m_lClientWidth Then
  319.             .Velocity.x = -1 * .Velocity.x
  320.         End If
  321.         
  322.         If .Location.y <= 0 Then
  323.             .Velocity.y = -1 * .Velocity.y
  324.         ElseIf .Location.y + .SpriteDimensions >= m_lClientHeight Then
  325.             .Velocity.y = -1 * .Velocity.y
  326.         End If
  327.     End With
  328. End Sub
  329. Private Function InitD3D(dx As DirectX8, d3d As Direct3D8, dev As Direct3DDevice8, ByVal hwnd As Long, Optional ByVal bWindowed As Boolean = True) As Long
  330.     '***********************************************************************
  331.     '
  332.     ' This function creates the following objects: DirectX8, Direct3D8,
  333.     ' Direc3DDevice8.
  334.     '
  335.     ' Parameters:
  336.     '
  337.     ' [IN]
  338.     '       hwnd:       Handle to a window that will be used as the render target
  339.     '       bWindowed:  Optional boolean argument that initializes either full screen
  340.     '                   or windowed. Default is windowed.
  341.     ' [OUT]
  342.     '       dx:         Pass in an uninitialized DirectX8 object.
  343.     '       d3d:        Pass in an uninitialized Direct3D8 object.
  344.     '       dev:        Pass in an uninitialized Direct3DDevice8 object.
  345.     '
  346.     ' Return value:
  347.     '
  348.     '     If an error occurs, it returns the Direct3D error number. In the
  349.     '     case that no fullscreen format was found, it returns D3DERR_INVALIDDEVICE.
  350.     '
  351.     '***********************************************************************
  352.     Dim DevType As CONST_D3DDEVTYPE
  353.     Dim i As Long, lCount As Long, lErrNum As Long, format As Long
  354.     Dim bFoundMode As Boolean
  355.         
  356.     'Turn off error checking. The app will check for errors and handle them.
  357.     On Local Error Resume Next
  358.     'Store the window mode that was passed in
  359.     m_bWindowed = bWindowed
  360.         
  361.     'Initiazlize the DirectX8 object
  362.     Set dx = New DirectX8
  363.         
  364.     'Check to make sure that the dx object was created successfully.
  365.     If Err.Number Then
  366.         'There were problems creating the dx object. Return the error number.
  367.         InitD3D = Err.Number
  368.         Exit Function
  369.         
  370.     End If
  371.     'Create the Direct3D object
  372.     Set d3d = dx.Direct3DCreate
  373.     'Check to make sure that the d3d object was created successfully.
  374.     If Err.Number Then
  375.         'There were problems creating the d3d object. Return the error number,
  376.         InitD3D = Err.Number
  377.         Exit Function
  378.         
  379.     End If
  380.     'We'll start by attempting to create a HAL device. This variable
  381.     'will hold the final type of device that we create after we check
  382.     'some capabilities.
  383.     DevType = D3DDEVTYPE_HAL
  384.     'Get the capabilities of the Direct3D device that we specify. In this case,
  385.     'we'll be using the adapter default (the primiary card on the system).
  386.     Call d3d.GetDeviceCaps(D3DADAPTER_DEFAULT, DevType, m_D3DCaps)
  387.     'Check for errors. If there is an error, the card more than likely doesn't support at least DX7,
  388.     'so get the caps of the reference device instead.
  389.     If Err.Number Then
  390.         
  391.         Err.Clear
  392.         DevType = D3DDEVTYPE_REF
  393.         Call d3d.GetDeviceCaps(D3DADAPTER_DEFAULT, DevType, m_D3DCaps)
  394.         
  395.         'If there is *still* an error, then the driver has problems. We'll
  396.         'have to exit at this point, because there isn't anything else we can
  397.         'do.
  398.         If Err.Number Then
  399.             InitD3D = D3DERR_NOTAVAILABLE
  400.             Exit Function
  401.         End If
  402.         
  403.     End If
  404.     'Grab some information about the current display mode.
  405.     Call d3d.GetAdapterDisplayMode(D3DADAPTER_DEFAULT, m_d3ddm)
  406.     'Now we'll go ahead and fill the D3DPRESENT_PARAMETERS type.
  407.     With m_d3dpp
  408.         
  409.         If bWindowed Then
  410.                         
  411.             'Make sure that the adapter is in a color bit-depth greater than 8 bits per pixel.
  412.             If m_d3ddm.format = D3DFMT_P8 Or m_d3ddm.format = D3DFMT_A8P8 Then
  413.                 'Device is running in some variation of an 8 bit format
  414.                 MsgBox " For this sample to run, the primary display needs to be in 16 bit or higher color depth.", vbCritical
  415.                 InitD3D = D3DERR_INVALIDDEVICE
  416.                 Exit Function
  417.             Else
  418.                 'Device is greater than 8 bit. Set the format variable to the current display format.
  419.                 format = m_d3ddm.format
  420.             End If
  421.             
  422.             'For windowed mode, we just discard any information instead of flipping it.
  423.             .SwapEffect = D3DSWAPEFFECT_DISCARD
  424.                         
  425.             'Set windowed mode to true.
  426.             .Windowed = 1
  427.                         
  428.         Else
  429.         
  430.             'Call the sub to find the first suitable fullscreen format
  431.             lErrNum = FindMode(FULLSCREENWIDTH, FULLSCREENHEIGHT, format)
  432.             
  433.             'If unable to find a suitable mode, the app will have to exit.
  434.             If lErrNum Then
  435.                 MsgBox " Unable to find a compatible format to run the sample.", vbCritical
  436.                 InitD3D = D3DERR_INVALIDDEVICE
  437.                 Exit Function
  438.             End If
  439.         
  440.             'We need the backbuffer to flip with the front for fullscreen. This
  441.             'flag enables this.
  442.             .SwapEffect = D3DSWAPEFFECT_FLIP
  443.                                     
  444.             'Set the width and height
  445.             .BackBufferWidth = FULLSCREENWIDTH
  446.             .BackBufferHeight = FULLSCREENHEIGHT
  447.             
  448.         End If
  449.         
  450.         'Set the backbuffer format
  451.         .BackBufferFormat = format
  452.     End With
  453.     'Try to create the device now that we have everything set.
  454.     Set dev = d3d.CreateDevice(D3DADAPTER_DEFAULT, DevType, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, m_d3dpp)
  455.     'If the creation above failed, try to create a REF device instead.
  456.     If Err.Number Then
  457.         
  458.         Err.Clear
  459.         Set dev = d3d.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, m_d3dpp)
  460.         
  461.         If Err.Number Then
  462.                     
  463.             'The app still hit an error. Both HAL and REF devices weren't created. The app will have to exit at this point.
  464.             InitD3D = Err.Number
  465.             Exit Function
  466.             
  467.         End If
  468.     End If
  469.     'Store the client dimensions
  470.     If m_bWindowed Then
  471.         m_lClientWidth = Me.ScaleWidth
  472.         m_lClientHeight = Me.ScaleHeight
  473.     Else
  474.         m_lClientWidth = FULLSCREENWIDTH
  475.         m_lClientHeight = FULLSCREENHEIGHT
  476.     End If
  477.     If InitDevice(dev, hwnd) Then
  478.         
  479.         MsgBox "Unable to initialize the device"
  480.         Unload Me
  481.         
  482.     End If
  483. End Function
  484. Private Function InitDevice(dev As Direct3DDevice8, hwnd As Long) As Long
  485.     '***********************************************************************
  486.     '
  487.     ' This function initializes the device with some renderstates, and also
  488.     ' sets up the viewport, camera, and world.
  489.     '
  490.     ' Parameters:
  491.     '
  492.     ' [IN]
  493.     '       dev:    An existing Direct3DDevice8 object
  494.     '       m_d3dpp:  A filled D3DPRESENT_PARAMETERS type
  495.     '       hwnd:   Handle to the target window
  496.     '
  497.     '
  498.     ' Return value:
  499.     '     If an error occurs, it returns D3DERR_INVALIDCALL.
  500.     '
  501.     '***********************************************************************
  502.     'On Local Error Resume Next
  503.     Call InitGeometry
  504.     With dev
  505.                 
  506.         'Set the vertex shader to an FVF that contains texture coords,
  507.         'and transformed and lit vertex coords.
  508.         Call .SetVertexShader(FVF)
  509.         
  510.         'Turn off lighting
  511.         Call .SetRenderState(D3DRS_LIGHTING, 0)
  512.                                 
  513.         'Set the render state that uses the alpha component as the source for blending.
  514.         Call .SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA)
  515.         
  516.         'Set the render state that uses the inverse alpha component as the destination blend.
  517.         Call .SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA)
  518.         
  519.     End With
  520.         
  521.     If Err.Number Then InitDevice = D3DERR_INVALIDCALL
  522. End Function
  523. Private Sub InitGeometry()
  524.     '***********************************************************************
  525.     '
  526.     ' This sub initializes the vertices for all the needed polygons.
  527.     '
  528.     ' Parameters:
  529.     '           None.
  530.     '
  531.     '***********************************************************************
  532.         
  533.     Dim sDimensions As Single
  534.     Dim i As Long
  535.     Static bInit As Boolean
  536.     ' All the polygons that this sample use are made of two triangles that create a rectangle.
  537.     ' The textures are painted on these two polygons to create the look of a 2d sprite.
  538.     ' All of the polygons are transformed and lit, meaning that Direct3D will perform no
  539.     ' lighting calculations, and no coordinate transformation. The application is responsible
  540.     ' for doing all of these calculations. Since this is just a 2d simulation, it's very easy
  541.     ' to set up the polygons and transform them manually.
  542.     ' This illustration shows the placement of each vertex (vn) to draw the rectangle. Notice the
  543.     ' order that the vertices are placed. This follows the clockwise winding order rule for culling
  544.     ' polygons. If the order was reversed, the polygon wouldn't be rendered by Direct3D. See the "3-D
  545.     ' Coordinate Systems and Geometry" section in the docs for more info.
  546.     ' * v1      * v3
  547.     ' |\        |
  548.     ' |  \      |
  549.     ' |    \    |
  550.     ' |      \  |
  551.     ' |        \|
  552.     ' * v0      * v2
  553.     'Initialize the 2 polygons that will display the DirectX logo
  554.     With m_MainVerts(0)
  555.         
  556.         'X and Y are the familiar XY values in screen space that this vertex will be placed.
  557.         'This one is going in the bottom left corner of the screen.
  558.         .x = 0: .y = m_lClientHeight
  559.         
  560.         'This sets up the texture coordinates for this vertex in the polygon.
  561.         'tu is the X of the texture, tv is the Y of the texture. Texture coordinates
  562.         'are from 0 to 1, 0 being all the way to the left or top, and 1 being all the
  563.         'way to the right or bottom, depending on whether it is the tu or tv element.
  564.         .tu = 0: .tv = 1
  565.         
  566.         'rhw is the value that D3D uses to produce scaling. Since this app
  567.         'won't be doing any scaling, this value needs to be 1.
  568.         .rhw = 1
  569.         
  570.         'Since the app will handle all lighting, the color value will be used
  571.         'to light the polygon. For this app, the polygon will be fully lit.
  572.         .color = &HFFFFFF
  573.     End With
  574.     'The rest of the vertices follow the same format, but are placed in different XY coordinates.
  575.     With m_MainVerts(1)
  576.         .x = 0: .y = 0
  577.         .tu = 0: .tv = 0
  578.         .rhw = 1
  579.         .color = &HFFFFFF
  580.     End With
  581.     With m_MainVerts(2)
  582.         .x = m_lClientWidth: .y = m_lClientHeight
  583.         .tu = 1: .tv = 1
  584.         .rhw = 1
  585.         .color = &HFFFFFF
  586.     End With
  587.     With m_MainVerts(3)
  588.         .x = m_lClientWidth: .y = 0
  589.         .tu = 1: .tv = 0
  590.         .rhw = 1
  591.         .color = &HFFFFFF
  592.     End With
  593.     For i = 0 To UBound(m_Sprite)
  594.                 
  595.         With m_Sprite(i)
  596.                     
  597.             'If this is the first time the sub is called.
  598.             If Not bInit Then
  599.             
  600.                 'Choose a random Sprite
  601.                 .SpriteNum = Int((3) * Rnd)
  602.                                         
  603.                 'Set the sprites properties accordingly
  604.                 If .SpriteNum = 0 Then
  605.                     .FramesPerRow = 8
  606.                     .FramesTotal = 29
  607.                     .RowOffset = 0
  608.                     .AnimDimensions = 0.125
  609.                     .SpriteDimensions = 40
  610.                 ElseIf .SpriteNum = 1 Then
  611.                     .FramesPerRow = 16
  612.                     .FramesTotal = 39
  613.                     .RowOffset = 0.5
  614.                     .AnimDimensions = 0.0625
  615.                     .SpriteDimensions = 15
  616.                 ElseIf .SpriteNum = 2 Then
  617.                     .FramesPerRow = 16
  618.                     .FramesTotal = 39
  619.                     .RowOffset = 0.6875
  620.                     .AnimDimensions = 0.0625
  621.                     .SpriteDimensions = 15
  622.                 End If
  623.             
  624.                 'Choose a random starting location, velocity, and animation frame
  625.                 .Location.x = (m_lClientWidth - .SpriteDimensions) * Rnd
  626.                 .Location.y = (m_lClientHeight - .SpriteDimensions) * Rnd
  627.                 .Velocity.x = (((MAX_VELOCITY - -MAX_VELOCITY) * Rnd) + -MAX_VELOCITY)
  628.                 .Velocity.y = (((MAX_VELOCITY - -MAX_VELOCITY) * Rnd) + -MAX_VELOCITY)
  629.                 .FrameCurrent = Int(.FramesTotal * Rnd)
  630.                 
  631.                 'Calculate the speed at which the animation should occurr. Based on the velocity of the sprite.
  632.                 'The higher the velocity, the faster the animation.
  633.                 .AnimSpeed = ((Abs(.Velocity.x) + Abs(.Velocity.y)) / 4)
  634.                                 
  635.             Else
  636.                 
  637.                 'The window was resized. Make sure sprites are still in view, move them so they are if neccessary.
  638.                 If .Location.x + .SpriteDimensions > m_lClientWidth Then
  639.                     .Location.x = m_lClientWidth - .SpriteDimensions - 1
  640.                 End If
  641.                 
  642.                 If .Location.y + .SpriteDimensions > m_lClientHeight Then
  643.                     .Location.y = m_lClientHeight - .SpriteDimensions - 1
  644.                 End If
  645.                                 
  646.             End If
  647.             
  648.             'Create the vertices for the Sprite
  649.             With .SpriteVerts(0)
  650.                 .x = 0: .y = 0
  651.                 .tu = 0: .tv = m_Sprite(i).AnimDimensions
  652.                 .rhw = 1
  653.                 .color = &HFFFFFF
  654.             End With
  655.             With .SpriteVerts(1)
  656.                 .x = 0: .y = m_Sprite(i).SpriteDimensions
  657.                 .tu = 0: .tv = 0
  658.                 .rhw = 1
  659.                 .color = &HFFFFFF
  660.             End With
  661.             With .SpriteVerts(2)
  662.                 .x = m_Sprite(i).SpriteDimensions: .y = 0
  663.                 .tu = m_Sprite(i).AnimDimensions: .tv = m_Sprite(i).AnimDimensions
  664.                 .rhw = 1
  665.                 .color = &HFFFFFF
  666.             End With
  667.             With .SpriteVerts(3)
  668.                 .x = m_Sprite(i).SpriteDimensions: .y = m_Sprite(i).SpriteDimensions
  669.                 .tu = m_Sprite(i).AnimDimensions: .tv = 0
  670.                 .rhw = 1
  671.                 .color = &HFFFFFF
  672.             End With
  673.             
  674.         End With
  675.         
  676.     Next
  677.     'The geometry is initialized. No need to randomize again.
  678.     bInit = True
  679. End Sub
  680. Private Sub InitTextures()
  681.     '***********************************************************************
  682.     '
  683.     ' This sub loads any textures needed. If for some reason this sub doesn't
  684.     ' succeed, we'll just exit the app, because it won't run without the
  685.     ' textures being loaded.
  686.     '
  687.     ' Parameters:
  688.     '           None.
  689.     '
  690.     '***********************************************************************
  691.     On Local Error Resume Next
  692.         
  693.     Dim sFile As String
  694.     'Locate the path to the media
  695.     sFile = FindMediaDir("dx5_logo.bmp")
  696.     If sFile = "" Then
  697.         sFile = App.Path & "\" & "dx5_logo.bmp"
  698.     Else
  699.         sFile = sFile & "dx5_logo.bmp"
  700.     End If
  701.     'Check to make sure the media was found
  702.     If Dir(sFile) = vbNullString Then
  703.         MsgBox "Unable to locate sample media."
  704.         Unload Me
  705.     End If
  706.     'Load the background texture
  707.     Set d3dtBackground = d3dx.CreateTextureFromFile(dev, sFile)
  708.         
  709.     'Locate the path to the next media file.
  710.     sFile = FindMediaDir("donuts1.bmp")
  711.     If sFile = "" Then
  712.         sFile = App.Path & "\" & "donuts1.bmp"
  713.     Else
  714.         sFile = sFile & "donuts1.bmp"
  715.     End If
  716.     'Check to make sure the media was found
  717.     If Dir(sFile) = vbNullString Then
  718.         MsgBox "Unable to locate sample media."
  719.         Unload Me
  720.     End If
  721.     'Load the Sprite texture. We need to get alpha information embedded into this
  722.     'surface, so we'll call the more complex CreateTextureFromFileEx() method instead.
  723.     'The main thing we need to do is just let it know we want to use black as the
  724.     'alpha channel. We do this by passing &HFF000000 to the method, and it fills in
  725.     'the high order byte of any pixel that contains black with full alpha so that it
  726.     'becomes transparent when rendered with alpha blending enabled.
  727.     Set d3dtSprite = d3dx.CreateTextureFromFileEx( _
  728.                                                     dev, _
  729.                                                     sFile, _
  730.                                                     D3DX_DEFAULT, _
  731.                                                     D3DX_DEFAULT, _
  732.                                                     D3DX_DEFAULT, _
  733.                                                     0, _
  734.                                                     D3DFMT_UNKNOWN, _
  735.                                                     D3DPOOL_MANAGED, _
  736.                                                     D3DX_FILTER_POINT, _
  737.                                                     D3DX_FILTER_POINT, _
  738.                                                     &HFF000000, _
  739.                                                     ByVal 0, _
  740.                                                     ByVal 0 _
  741.                                                     )
  742.             
  743.     If Err.Number Then
  744.         
  745.         'Something happened while loading the texture.
  746.         MsgBox "Error loading texture. Error number: " & Err.Number
  747.         Unload Me
  748.         
  749.     End If
  750. End Sub
  751. Private Sub SwitchWindowMode()
  752.     '***********************************************************************
  753.     '
  754.     ' This sub switches the current display mode between windowed/fullscreen.
  755.     ' If it runs into an error, it just exits, leaving the display mode in
  756.     ' its current state.
  757.     '
  758.     ' Parameters:
  759.     '           None.
  760.     '
  761.     '***********************************************************************
  762.     Dim d3dppEmpty As D3DPRESENT_PARAMETERS
  763.     Dim format As Long
  764.     Dim lErrNum As Long
  765.     On Local Error Resume Next
  766.     If m_bWindowed Then
  767.                                     
  768.         'Grab a valid format for this device. If a format
  769.         'for the requested resolution wasn't found, exit the sub.
  770.         If FindMode(FULLSCREENWIDTH, FULLSCREENHEIGHT, format) <> 0 Then Exit Sub
  771.                 
  772.         'Store the current window mode format
  773.         Call d3d.GetAdapterDisplayMode(D3DADAPTER_DEFAULT, m_d3ddm)
  774.         
  775.         'The app is running windowed currently, switch to fullscreen.
  776.         m_bWindowed = False
  777.                 
  778.         'Set the present parameters for running full screen
  779.         m_d3dpp = d3dppEmpty
  780.         
  781.         With m_d3dpp
  782.             .SwapEffect = D3DSWAPEFFECT_FLIP
  783.             .BackBufferFormat = format
  784.             .BackBufferWidth = FULLSCREENWIDTH
  785.             .BackBufferHeight = FULLSCREENHEIGHT
  786.             .Windowed = 0
  787.         End With
  788.         
  789.         'Store the client dimensions
  790.         m_lClientWidth = FULLSCREENWIDTH
  791.         m_lClientHeight = FULLSCREENHEIGHT
  792.         
  793.         'Reset the device to the new mode
  794.         lErrNum = ResetDevice
  795.         
  796.         'If there is an error resetting the device,
  797.         'just exit the sub.
  798.         If lErrNum Then
  799.             'Store the client dimensions
  800.             m_lClientWidth = Me.ScaleWidth
  801.             m_lClientHeight = Me.ScaleHeight
  802.             m_bWindowed = True
  803.             Exit Sub
  804.         End If
  805.                 
  806.     Else
  807.                                                                                                     
  808.         'Set the present params to reflect windowed operation.
  809.         m_d3dpp = d3dppEmpty
  810.         
  811.         With m_d3dpp
  812.             .SwapEffect = D3DSWAPEFFECT_DISCARD
  813.             .BackBufferFormat = m_d3ddm.format
  814.             .Windowed = 1
  815.         End With
  816.         
  817.         'Reset the device to the new mode
  818.         lErrNum = ResetDevice
  819.         
  820.         'If there is an error, just exit the sub
  821.         If lErrNum Then
  822.             m_bWindowed = False
  823.             Exit Sub
  824.         End If
  825.           
  826.         'Now get the device ready again
  827.         Call InitDevice(dev, Me.hwnd)
  828.               
  829.         'Resize the form to the size it was previous to going fullscreen.
  830.         Me.Width = m_lWindowWidth * Screen.TwipsPerPixelX
  831.         Me.Height = m_lWindowHeight * Screen.TwipsPerPixelY
  832.         
  833.         'The app is now running windowed
  834.         m_bWindowed = True
  835.         
  836.         'Store the client dimensions
  837.         m_lClientWidth = Me.ScaleWidth
  838.         m_lClientHeight = Me.ScaleHeight
  839.         
  840.         'Resize the window to the old size now.
  841.         Call Form_Resize
  842.         
  843.     End If
  844. End Sub
  845. Private Sub ResizeWindow()
  846.     '***********************************************************************
  847.     '
  848.     ' This subroutine is called whenever the form is resized. It resets the
  849.     ' device to the new size, and re-inits the device.
  850.     '
  851.     ' Parameters:
  852.     '
  853.     '   None.
  854.     '
  855.     '***********************************************************************
  856.     Dim d3dppEmpty As D3DPRESENT_PARAMETERS
  857.             
  858.     m_lWindowWidth = Me.ScaleWidth
  859.     m_lWindowHeight = Me.ScaleHeight
  860.     m_lClientWidth = m_lWindowWidth
  861.     m_lClientHeight = m_lWindowHeight
  862.     'Reset the device to the new mode
  863.     Call ResetDevice
  864. End Sub
  865. Private Function ResetDevice() As Long
  866.     '***********************************************************************
  867.     '
  868.     ' This subroutine is called whenever the app needs to be resized, or the
  869.     ' device has been lost.
  870.     '
  871.     ' Parameters:
  872.     '
  873.     '   None.
  874.     '
  875.     '***********************************************************************
  876.         
  877.     On Local Error Resume Next
  878.     Call dev.Reset(m_d3dpp)
  879.     If Err.Number Then
  880.         ResetDevice = Err.Number
  881.         Exit Function
  882.     End If
  883.     'Now get the device ready again
  884.     Call InitDevice(dev, Me.hwnd)
  885. End Function
  886. Private Function FindMode(ByVal w As Long, ByVal h As Long, fmt As Long) As Long
  887.     '***********************************************************************
  888.     '
  889.     ' This function returns a valid back buffer format for the width and height passed in.
  890.     '
  891.     ' Parameters:
  892.     '
  893.     ' [IN]
  894.     '      w is the width of the mode being sought
  895.     '      h is the height of the mode being sought
  896.     '
  897.     ' [OUT]
  898.     '     fmt will be filled in with a valid CONST_D3DFORMAT
  899.     '
  900.     ' Return value:
  901.     '     If a valid format was not found, D3DERR_INVALIDDEVICE is returned.
  902.     '     If an error occurs, it returns D3DERR_INVALIDCALL.
  903.     '***********************************************************************
  904.     Dim i  As Long, lCount As Long
  905.     Dim d3ddm As D3DDISPLAYMODE
  906.     Dim bFoundMode As Boolean
  907.     i = 0
  908.     'Get the number of adapter modes this adapter supports.
  909.     lCount = d3d.GetAdapterModeCount(D3DADAPTER_DEFAULT) - 1
  910.     'If we encounter an error, return an error code and exit the function.
  911.     If Err.Number Then
  912.         FindMode = D3DERR_INVALIDCALL
  913.         Exit Function
  914.     End If
  915.     'Next, loop through all the display modes until we find one
  916.     'that matches the parameters passed in.
  917.     For i = 0 To lCount
  918.         
  919.         Call d3d.EnumAdapterModes(D3DADAPTER_DEFAULT, i, d3ddm)
  920.         
  921.         'Again, catch any unexpected errors.
  922.         If Err.Number Then
  923.             FindMode = Err.Number
  924.             Exit Function
  925.         End If
  926.         
  927.         'Check to see if this mode matches what is being sought.
  928.         If d3ddm.Width = w And d3ddm.Height = h Then
  929.             
  930.             'Now see if this mode is either a 32bpp or 16bpp mode
  931.             If d3ddm.format = D3DFMT_R8G8B8 Or _
  932.                 d3ddm.format = D3DFMT_R5G6B5 Then
  933.                 
  934.                 'We've found a suitable display. Set the flag
  935.                 'to reflect this, and exit. No need to look further.
  936.                 bFoundMode = True
  937.                 
  938.                 'Set the fmt to the format that was found.
  939.                 fmt = d3ddm.format
  940.                 
  941.                 Exit For
  942.             End If
  943.         End If
  944.     Next
  945.         
  946.     If bFoundMode Then
  947.         
  948.         'Everything checked out OK
  949.         Exit Function
  950.         
  951.     Else
  952.         
  953.         'Return an error
  954.         FindMode = D3DERR_INVALIDDEVICE
  955.         
  956.     End If
  957. End Function
  958. Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
  959.     If (Shift And vbAltMask) And KeyCode = vbKeyReturn Then
  960.         
  961.         'User wants to switch from fullscreen/windowed mode
  962.         Call SwitchWindowMode
  963.             
  964.     ElseIf KeyCode = vbKeyEscape Then
  965.         
  966.         'User wants to exit the app
  967.         m_bRunning = False
  968.         
  969.     End If
  970.                         
  971. End Sub
  972. Private Sub Form_Resize()
  973.     'Call the subroutine that resizes the backbuffer on the device.
  974.     'Make sure the device exists, and the app is windowed.
  975.     If Not dev Is Nothing And m_bWindowed Then
  976.         
  977.     'Make sure the app isn't minimized.
  978.     If Me.WindowState <> vbMinimized Then
  979.         
  980.         'Make sure the app isn't resized to the point where the sprites could get stuck.
  981.         If Me.ScaleHeight < 100 Or Me.ScaleWidth < 100 Then
  982.             Me.Width = Screen.TwipsPerPixelX * 100
  983.             Me.Height = Screen.TwipsPerPixelY * 100
  984.         End If
  985.         
  986.             Call ResizeWindow
  987.         End If
  988.         
  989.     End If
  990. End Sub
  991. Private Sub Form_Unload(Cancel As Integer)
  992.     'We need to terminate the app using the End statement,
  993.     'otherwise the form will reload since the app is running
  994.     'in a loop with DoEvents.
  995.     End
  996. End Sub
  997.